package com.sky.controller.user;

import cn.dev33.satoken.annotation.SaIgnore;
import com.sky.constant.MessageConstant;
import com.sky.dto.ResetPasswordDTO;
import com.sky.dto.ResetPasswordEmailDTO;
import com.sky.entity.Users;
import com.sky.exception.BaseException;
import com.sky.result.Result;
import com.sky.service.EmailService;
import com.sky.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 用户密码相关接口
 */
@RestController
@RequestMapping("/user/password")
@Slf4j
public class UserPasswordController {

    @Autowired
    private EmailService emailService;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 发送重置密码验证码
     * 验证码有效期为15分钟
     *
     * @param resetPasswordEmailDTO 重置密码邮件信息（仅包含邮箱）
     * @return Result
     */
    @SaIgnore
    @PostMapping("/reset/code")
    public Result sendResetPasswordCode(@RequestBody @Valid ResetPasswordEmailDTO resetPasswordEmailDTO) {
        log.info("发送重置密码验证码：{}", resetPasswordEmailDTO);
        
        // 根据邮箱查询用户
        Users user = userService.getUserByEmail(resetPasswordEmailDTO.getEmail());
        if (user == null) {
            throw new BaseException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        // 生成6位随机验证码
        String verificationCode = String.format("%06d", new Random().nextInt(1000000));

        // 将验证码保存到Redis，设置15分钟过期
        String redisKey = "reset_password_code:" + resetPasswordEmailDTO.getEmail();
        redisTemplate.opsForValue().set(redisKey, verificationCode, 15, TimeUnit.MINUTES);

        // 发送验证码邮件
        emailService.sendResetPasswordVerificationCode(
            resetPasswordEmailDTO.getEmail(),
            user.getUsername(),
            verificationCode
        );

        return Result.success();
    }

    /**
     * 重置密码
     * 需要验证邮箱验证码
     *
     * @param resetPasswordDTO 重置密码信息（包含邮箱、验证码和新密码）
     * @return Result
     */
    @SaIgnore
    @PostMapping("/reset")
    public Result resetPassword(@RequestBody @Valid ResetPasswordDTO resetPasswordDTO) {
        log.info("重置密码：{}", resetPasswordDTO);

        // 验证码校验
        String redisKey = "reset_password_code:" + resetPasswordDTO.getEmail();
        String storedCode = (String) redisTemplate.opsForValue().get(redisKey);
        
        if (storedCode == null) {
            throw new BaseException(MessageConstant.VERIFICATION_CODE_EXPIRED);
        }
        
        if (!storedCode.equals(resetPasswordDTO.getVerificationCode())) {
            throw new BaseException(MessageConstant.VERIFICATION_CODE_ERROR);
        }

        // 重置密码
        Users user = userService.getUserByEmail(resetPasswordDTO.getEmail());
        if (user == null) {
            throw new BaseException(MessageConstant.ACCOUNT_NOT_FOUND);
        }

        // 更新密码
        userService.resetPasswordByEmail(resetPasswordDTO.getEmail(), resetPasswordDTO.getNewPassword());

        // 删除验证码
        redisTemplate.delete(redisKey);

        return Result.success();
    }
} 